#include "os_sal.h"


/* os timer 软件定时器 */


/* export func */


#if (CONFIG_OS_ENABLE == 1)

#if defined(CONFIG_OS_TYPE_FREERTOS)

#include "FreeRTOS.h"
#include "timers.h"

/**
 * @brief OS创建软定时器
 * 
 * @param name 定时器名
 * @param func 定时器回调函数
 * @param ticks 周期(单位是时钟节拍)
 * @param reload 定时器模式 os_true:周期 os_false:单次
 * @param id 定时器ID
 * @return os_timer_handle_t 定时器句柄
 */
os_timer_handle_t os_timer_create(const char *name, 
									void (*func)(os_timer_handle_t xtimer),
									uint32_t ticks, 
									os_bool_t reload,
									void *id)
{
	os_timer_handle_t timer;

	if (func == NULL || id == NULL) return NULL;
	timer = xTimerCreate(name, ticks, reload, id, (TimerCallbackFunction_t)func);
	return timer;
}

/**
 * @brief OS删除软定时器
 * 
 * @param timer 定时器句柄
 * @param waittime 等待时间
 * @return os_status_t 
 */
os_status_t os_timer_delete(os_timer_handle_t timer, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;

	if (timer == NULL) return OS_STA_ERROR;
	err = xTimerDelete(timer, waittime);
	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;
	return os_sta;
}

/**
 * @brief OS启动软定时器
 * 
 * @param timer 定时器句柄
 * @param waittime 等待时间
 * @return os_status_t 
 */
os_status_t os_timer_start(os_timer_handle_t timer, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (timer == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xTimerStartFromISR(timer, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xTimerStart(timer, waittime);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}

/**
 * @brief OS停止软定时器
 * 
 * @param timer 定时器句柄
 * @param waittime 等待时间
 * @return os_status_t 
 */
os_status_t os_timer_stop(os_timer_handle_t timer, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (timer == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xTimerStopFromISR(timer, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xTimerStop(timer, waittime);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}

/**
 * @brief OS停止软定时器
 * 
 * @param timer 定时器句柄
 * @param ticks 目标时间
 * @param waittime 等待时间
 * @return os_status_t 
 */
os_status_t os_timer_change(os_timer_handle_t timer, uint32_t ticks, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (timer == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xTimerChangePeriodFromISR(timer, ticks, &pxHigherPriorityTaskWoken);
		xTimerStartFromISR(timer, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xTimerChangePeriod(timer, ticks, waittime);
		xTimerStart(timer, waittime);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}




#else
    #error "CONFIG_OS_TYPE not support!"
#endif // CONFIG_OS_TYPE

#endif // CONFIG_OS_ENABLE


